#ifndef     __MESSAGE_H
#define     __MESSAGE_H

#include "./conn_info.h"
#include "./conn_type.h"
#include "../utils/decode.h"

namespace conn {

struct Message {

public:
    static Message from_can(const ConnInfo &info, const uint8_t *buf, uint8_t len) {
        Message msg;
        msg.conn_info = info;
        msg.conn_type = ConnType::CAN;
        msg.data_buf = buf;
        msg.data_len = len;
		return msg;
    }

    static Message from_rs232(const uint8_t *buf, uint8_t len) {
        Message msg;
        msg.conn_info = ConnInfo::from_rs232(buf);
        msg.data_buf = buf + 6;
        msg.data_len = len - 8;
        msg.conn_type = ConnType::RS232;
		return msg;
    }

    template <typename... Ts>
    inline utils::Error parse(Ts&&... ts) const {
        using namespace utils;
        return decode_all(data_buf, data_len, std::forward<Ts>(ts)...) ? ec::OK : ec::PARSE_FAIL;
    }

    inline utils::Error parse_ec() const {
        uint8_t ec;
        utils::Error err = parse(ec);
        if (err) {
            return err;
        }
        return ec;
    }

    ConnInfo conn_info;
    ConnType conn_type;
    const uint8_t *data_buf;
    uint8_t data_len;
};

}

#endif
